package com.apes.fn.server.workOrder.service;

import com.apes.fn.crm.customerExpand.FnCustomerExpand;
import com.apes.fn.server.servicePlan.model.ServicePlan;
import com.apes.fn.server.servicePlan.model.ServicePlanItem;
import com.apes.fn.server.workOrder.model.ConstructionRecord;
import com.apes.fn.server.workOrder.model.MaintenanceOrder;
import com.apes.fn.server.workOrder.model.MaintenanceOrderReport;
import com.apes.fn.server.workOrder.repository.ConstructRecordRepository;
import com.apes.fn.server.workOrder.repository.MaintenanceOrderReportRepository;
import com.apes.fn.server.workOrder.repository.MaintenanceOrderRepository;
import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.plugin.mq.MQUtil;
import com.apes.framework.plugin.mq.annotation.Consumer;
import com.apes.framework.plugin.outbox.OutboxEvent;
import com.apes.framework.plugin.outbox.OutboxEventRepository;
import com.apes.framework.plugin.outbox.annotation.OutboxSubscriber;
import com.apes.framework.util.DateUtil;
import com.apes.framework.util.MapUtil;
import com.apes.scm.contract.model.Contract;
import com.apes.scm.masterdata.frame.model.Dept;
import com.apes.scm.masterdata.party.model.PartyRole;
import com.apes.scm.masterdata.party.repository.PartyRoleRepository;
import com.apes.scm.masterdata.product.model.Product;
import com.apes.scm.masterdata.product.model.ProductServiceHours;
import com.apes.scm.masterdata.product.model.ProductUom;
import com.apes.scm.masterdata.product.model.ServeType;
import com.apes.scm.masterdata.product.repository.ProductServiceHoursRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * Creator: zouyc
 * CreateDate: 2020-12-01 10:36
 * Description:
 **/
@Service("maintenanceOrderReportService")
public class MaintenanceOrderReportService extends DomainService {
    @Autowired
    MaintenanceOrderReportRepository maintenanceOrderReportRepository;
    @Autowired
    MaintenanceOrderRepository maintenanceOrderRepository;
    @Autowired
    ConstructRecordRepository constructRecordRepository;
    @Autowired
    OutboxEventRepository outboxEventRepository;


    public void setMaintenanceOrderReportHis(SimpleRequest re){
        if(re.getJO().getBoolean("outbox") == true){ //跑outbox数据
            Sort sort = new Sort(Sort.Direction.ASC, "id");
            int page  = 0;
            while(true){
                List<OutboxEvent> outboxEvents =
                        outboxEventRepository.findAll(JpaDsl.toCriteriaByEq("subscriber","local.MaintenanceOrderReportService.constructMaintenanceOrderReportEvent","state", 1),PageRequest.of(page, 1000,sort)).getContent();
                outboxEvents.forEach(outboxEvent -> {
                    MQUtil.publish("maintenanceOrderReport.report.create", "工单生成报表", MapUtil.mapper("id",outboxEvent.getAggregateId()));
                });
                if (outboxEvents.size() < 1000) {
                    break;
                }
                page ++;
            }
        }else if(re.getJO().getBoolean("all") == true){ //跑全部数据
            Sort sort = new Sort(Sort.Direction.ASC, "id");
            int page  = 0;
            while(true){
                List<MaintenanceOrder> list = maintenanceOrderRepository.findAll(PageRequest.of(page, 1000,sort)).getContent();
                list.forEach(maintenanceOrder -> {
                    MQUtil.publish("maintenanceOrderReport.report.create", "工单生成报表", MapUtil.mapper("id",maintenanceOrder.getId()));
                });
                if (list.size() < 1000) {
                    break;
                }
                page ++;
            }
        }else if(re.getJO().getDate("startDate") != null && re.getJO().getDate("endDate") != null){
            Date startDate = re.getJO().getDate("startDate");
            Date endDate = re.getJO().getDate("endDate");
            Sort sort = new Sort(Sort.Direction.ASC, "id");
            int page  = 0;
            while(true){
                List<MaintenanceOrder> list =
                        maintenanceOrderRepository.findAll(JpaDsl.toCriteria("createDate","GTE",startDate,"createDate","LTE",endDate),PageRequest.of(page, 1000,sort)).getContent();
                list.forEach(maintenanceOrder -> {
                    MQUtil.publish("maintenanceOrderReport.report.create", "工单生成报表", MapUtil.mapper("id",maintenanceOrder.getId()));
                });
                if (list.size() < 1000) {
                    break;
                }
                page ++;
            }
        }
    }

    @Consumer(topic = "maintenanceOrderReport.report.create")
    public void consumerCreateReport(SimpleRequest re){
        maintenanceOrderReportRepository.saveAndFlush(constructMaintenanceOrderReport(maintenanceOrderRepository.findOne(re.getJO().getString("id"))));
    }

    @OutboxSubscriber(name = "创建更新工单查询报表")
    public void constructMaintenanceOrderReportEvent(MaintenanceOrder maintenanceOrder){
        MaintenanceOrderReport maintenanceOrderReport = constructMaintenanceOrderReport(maintenanceOrder);
        if(maintenanceOrderReport != null){
            maintenanceOrderReportRepository.saveAndFlush(maintenanceOrderReport);
        }

    }



    /**
     * 根据工单创建工单查询表
     * @param maintenanceOrder
     * @return
     */
    private MaintenanceOrderReport constructMaintenanceOrderReport(MaintenanceOrder maintenanceOrder){
        maintenanceOrder = maintenanceOrderRepository.findOne(maintenanceOrder.getId());
        MaintenanceOrderReport maintenanceOrderReport = maintenanceOrderReportRepository.findOne(maintenanceOrder.getId()) ;
        maintenanceOrderReport = maintenanceOrderReport == null ? new MaintenanceOrderReport() : maintenanceOrderReport;

        ServicePlanItem servicePlanItem = maintenanceOrder.getServicePlanItem();
        ServicePlan servicePlan = servicePlanItem.getServicePlan();
        FnCustomerExpand fnCustomerExpand = maintenanceOrder.getFnCustomerExpand();
        Product product = maintenanceOrder.getProduct();
        ProductUom uom = maintenanceOrder.getUom();

        maintenanceOrderReport.setId(maintenanceOrder.getId());
        maintenanceOrderReport.setServicePlanItemId(servicePlanItem.getId());
        maintenanceOrderReport.setServicePlanId(servicePlan.getId());

        maintenanceOrderReport.setBusinessType(maintenanceOrder.getBusinessType());
        maintenanceOrderReport.setBusinessTypeName(maintenanceOrder.getBusinessTypeName());
        maintenanceOrderReport.setPlanSourceFrom(servicePlan.getSourceFrom());
        maintenanceOrderReport.setPlanSourceTypeName(servicePlan.getSourceBusinessTypeName());
        maintenanceOrderReport.setSourceType(maintenanceOrder.getSourceType());
        maintenanceOrderReport.setSourceFrom(maintenanceOrder.getSourceFrom());
        maintenanceOrderReport.setState(maintenanceOrder.getState());
        maintenanceOrderReport.setWorkState(maintenanceOrder.getWorkState());
        maintenanceOrderReport.setDispatcheState(maintenanceOrder.getDispatcheState());
        maintenanceOrderReport.setLockState(maintenanceOrder.isLockState());
        maintenanceOrderReport.setOutAssistType(maintenanceOrder.getOutAssistType());
        maintenanceOrderReport.setOutAssistTypeConfirm(maintenanceOrder.isOutAssistTypeConfirm());

        maintenanceOrderReport.setFnCustomerExpandId(fnCustomerExpand.getId());
        maintenanceOrderReport.setCarLicense(fnCustomerExpand.getCarLicense());
        maintenanceOrderReport.setMobile(fnCustomerExpand.getMobile());
        maintenanceOrderReport.setREALNAME(fnCustomerExpand.getRealname());

        maintenanceOrderReport.setProductId(product.getId());
        maintenanceOrderReport.setProductName(product.getName());
        maintenanceOrderReport.setUom(uom.getId());
        maintenanceOrderReport.setUomName(uom.getName());
        maintenanceOrderReport.setSaleQty(maintenanceOrder.getSaleQty());
        maintenanceOrderReport.setProductRule(maintenanceOrder.isProductRule());

        ProductServiceHours productServiceHours =
                SpringManager.getBean(ProductServiceHoursRepository.class).findAll(JpaDsl.toCriteriaByEq("valid",true,"product.id",product.getId())).stream().findFirst().orElse(null);
        if(productServiceHours != null){
            maintenanceOrderReport.setSTANDERHOUR(productServiceHours.getServiceHours());
        }

        ServeType serveType = servicePlanItem.getServeType();
        if(serveType != null){
            maintenanceOrderReport.setServeTypeId(servicePlanItem.getServeType().getId());
            maintenanceOrderReport.setServeTypeName(servicePlanItem.getServeType().getName());
        }


        maintenanceOrderReport.setOutAssistRemark(maintenanceOrder.getOutAssistRemark());
        maintenanceOrderReport.setWorkPlatform(maintenanceOrder.getWorkPlatform());
        maintenanceOrderReport.setPoint(maintenanceOrder.getPoint());
        Contract contract = maintenanceOrder.getContract();
        if(contract != null){
            maintenanceOrderReport.setContract(maintenanceOrder.getContract().getId());
            maintenanceOrderReport.setContractName(maintenanceOrder.getContract().getName());
        }
        PartyRole platform =  maintenanceOrder.getPlatform();
        if(platform != null){
            maintenanceOrderReport.setPlatform(maintenanceOrder.getPlatform().getId());
            maintenanceOrderReport.setPlatformName(maintenanceOrder.getPlatform().getName());
        }

        maintenanceOrderReport.setBelongDeptId(maintenanceOrder.getBelongDept().getId());
        maintenanceOrderReport.setBelongDeptName(maintenanceOrder.getBelongDept().getName());
        maintenanceOrderReport.setCompany(maintenanceOrder.getCompany().getId());
        maintenanceOrderReport.setCompanyName(maintenanceOrder.getCompany().getName());
        Dept innerDept = maintenanceOrder.getInnerDept();
        if(innerDept != null){
            maintenanceOrderReport.setInnerDeptId(maintenanceOrder.getInnerDept().getId());
            maintenanceOrderReport.setInnerDeptName(maintenanceOrder.getInnerDept().getName());
        }

        maintenanceOrderReport.setPlatformPriceCosInTax(maintenanceOrder.getPlatformPriceCosInTax());
        maintenanceOrderReport.setPriceCostUnitInTax(maintenanceOrder.getPriceCostUnitInTax());
        maintenanceOrderReport.setPlatformPriceCosInTaxTemp(maintenanceOrder.getPlatformPriceCosInTaxTemp());
        maintenanceOrderReport.setPriceCostUnitInTaxTemp(maintenanceOrder.getPriceCostUnitInTaxTemp());

        PartyRole tRole = maintenanceOrder.getTerminationUid();
        PartyRole fRole = maintenanceOrder.getFinishUid();
        PartyRole iRole = maintenanceOrder.getToInnerUid();
        PartyRole dRole = maintenanceOrder.getDispatchUid();
        PartyRole dbRole = maintenanceOrder.getDispatchBackUid();
        PartyRole obRole = maintenanceOrder.getOutBackUid();
        PartyRole toRole = maintenanceOrder.getToOutUid();

        PartyRole cRole = null;
        if(maintenanceOrder.getCreator() != null){
            cRole = SpringManager.getBean(PartyRoleRepository.class).findOne(maintenanceOrder.getCreator());
        }
        if(cRole != null){
            maintenanceOrderReport.setCreatorName(cRole.getName());
        }

        if(tRole != null){
            maintenanceOrderReport.setTerminationUid(tRole.getId());
            maintenanceOrderReport.setTerminationUName(tRole.getName());
        }
        if(fRole != null){
            maintenanceOrderReport.setFinishUid(fRole.getId());
            maintenanceOrderReport.setFinishUName(fRole.getName());
        }
        if(iRole != null){
            maintenanceOrderReport.setToInnerUid(iRole.getId());
            maintenanceOrderReport.setToInnerUName(iRole.getName());
        }
        if(dRole != null){
            maintenanceOrderReport.setDispatchUid(dRole.getId());
            maintenanceOrderReport.setDispatchUName(dRole.getName());
        }
        if(dbRole != null){
            maintenanceOrderReport.setDispatchBackUid(dbRole.getId());
            maintenanceOrderReport.setDispatchBackUName(dbRole.getName());
        }
        if(obRole != null){
            maintenanceOrderReport.setOutBackUid(obRole.getId());
            maintenanceOrderReport.setOutBackUName(obRole.getName());
        }
        if(toRole != null){
            maintenanceOrderReport.setToOutUid(toRole.getId());
            maintenanceOrderReport.setToOutUName(toRole.getName());
        }

        maintenanceOrderReport.setWorker1(maintenanceOrder.getWorker1());
        maintenanceOrderReport.setWorker1Show(maintenanceOrder.getWorker1Show());
        maintenanceOrderReport.setWorker2(maintenanceOrder.getWorker2());
        maintenanceOrderReport.setWorker2Show(maintenanceOrder.getWorker2Show());
        maintenanceOrderReport.setWorker3(maintenanceOrder.getWorker3());
        maintenanceOrderReport.setWorker3Show(maintenanceOrder.getWorker3Show());
        maintenanceOrderReport.setWorker4(maintenanceOrder.getWorker4());
        maintenanceOrderReport.setWorker4Show(maintenanceOrder.getWorker4Show());

        maintenanceOrderReport.setTerminationDate(maintenanceOrder.getTerminationDate());
        maintenanceOrderReport.setFinishDate(maintenanceOrder.getFinishDate());
        maintenanceOrderReport.setWorkStartTime(maintenanceOrder.getWorkStartTime());
        maintenanceOrderReport.setToInnerDate(maintenanceOrder.getToInnerDate());
        maintenanceOrderReport.setDispatchDate(maintenanceOrder.getDispatchDate());
        maintenanceOrderReport.setOutBackDate(maintenanceOrder.getOutBackDate());
        maintenanceOrderReport.setDispatchBackDate(maintenanceOrder.getDispatchBackDate());
        maintenanceOrderReport.setToOutDate(maintenanceOrder.getToOutDate());
        maintenanceOrderReport.setWorkedTime(maintenanceOrder.getWorkedTime());
        maintenanceOrderReport.setPauseedTime(maintenanceOrder.getPauseedTime());
        maintenanceOrderReport.setPointStartTime(maintenanceOrder.getPointStartTime());
        maintenanceOrderReport.setReachDate(maintenanceOrder.getReachDate());
        maintenanceOrderReport.setCreateDate(maintenanceOrder.getCreateDate());

        return maintenanceOrderReport;
    }




    //---------------------------------------------------------------
    public void setMaintenanceOrderReportHisC(SimpleRequest re){
        Sort sort = new Sort(Sort.Direction.ASC, "id");
        int page  = 0;
        List<String> strings = new ArrayList<>();
        strings.add("start");
        strings.add("finish");
        while(true){
            List<ConstructionRecord> list = constructRecordRepository.findAll(JpaDsl.toCriteria("operateType","IN",strings),PageRequest.of(page, 1000,sort)).getContent();
            list.forEach(constructionRecord -> {
                MQUtil.publish("maintenanceOrderReportC.report.create", "工单生成报表", MapUtil.mapper("id",constructionRecord.getId()));
            });
            if (list.size() < 1000) {
                break;
            }
            page ++;
        }
    }

    @Consumer(topic = "maintenanceOrderReportC.report.create")
    public void consumerCreateReportC(SimpleRequest re){
        maintenanceOrderReportRepository.saveAndFlush(constructMaintenanceOrderReport(constructRecordRepository.findOne(re.getJO().getString("id"))));
    }

    @OutboxSubscriber(name = "创建更新工单查询报表(施工记录)")
    public void constructMaintenanceOrderReportEventC(ConstructionRecord constructionRecord){
        maintenanceOrderReportRepository.saveAndFlush(constructMaintenanceOrderReport(constructionRecord));
    }

    /**
     * 工单开始时间，结束时间
     * @param constructionRecord
     * @return
     */
    private MaintenanceOrderReport constructMaintenanceOrderReport(ConstructionRecord constructionRecord){
        MaintenanceOrderReport maintenanceOrderReport = maintenanceOrderReportRepository.findOne(constructionRecord.getMaintenanceOrder().getId());
        maintenanceOrderReport = maintenanceOrderReport == null ? new MaintenanceOrderReport() : maintenanceOrderReport;
        maintenanceOrderReport.setId(constructionRecord.getMaintenanceOrder().getId());
        if("start".equals(constructionRecord.getOperateType())){
            maintenanceOrderReport.setWORKSTART(constructionRecord.getCreateDate());
        }
        if("finish".equals(constructionRecord.getOperateType())){
            maintenanceOrderReport.setWORKEND(constructionRecord.getCreateDate());
        }
        return  maintenanceOrderReport;
    }




}
